//! 通用工具函数模块

use librarys::random_letters;
use serde_json::Value;
use crate::generators::{number, datetime, internet};

/// 根据表结构生成数据
pub fn generate_sample_data_by_schema(schema: &crate::db::schema::TableSchema, _id: usize) -> Value {
    use crate::generation::DataForge;
    use crate::db::schema::DataType;
    // use rand::seq::SliceRandom;
    
    let mut data = serde_json::Map::new();
    
    // 使用 data-forge 的核心生成能力
    let forge = DataForge::new(crate::generation::Language::ZhCN);
    
    // 根据表结构动态生成数据，完全基于字段类型而不是字段名称
    for field in &schema.fields {
        let value = match &field.data_type {
            // 字符串类型字段 - 完全基于字段类型生成，不依赖字段名称
            DataType::String { max_length } => {
                let max_len = max_length.unwrap_or(255) as usize;
                // 使用 data-forge 的随机字符串生成能力
                Value::String(random_letters(std::cmp::min(10, max_len)))
            },
            // 整数类型字段 - 完全基于字段类型生成，不依赖字段名称
            DataType::Integer { .. } => {
                // 使用 data-forge 的数字生成能力
                forge.generate("random_int").unwrap_or_else(|| {
                    Value::Number(serde_json::Number::from(number::random_int(0, 1000000)))
                })
            },
            // 浮点数类型字段 - 完全基于字段类型生成，不依赖字段名称
            DataType::Float { .. } => {
                // 使用 data-forge 的浮点数生成能力
                forge.generate("random_float").unwrap_or_else(|| {
                    Value::Number(serde_json::Number::from_f64(number::random_float(0.0, 1000.0)).unwrap())
                })
            },
            // 布尔类型字段 - 完全基于字段类型生成，不依赖字段名称
            DataType::Boolean => { 
                // 使用 data-forge 的布尔值生成能力
                forge.generate("random_bool").unwrap_or_else(|| {
                    Value::Bool(rand::random())
                })
            },
            // 日期时间类型字段 - 完全基于字段类型生成，不依赖字段名称
            DataType::DateTime { .. } => {
                // 使用 data-forge 的日期时间生成能力
                forge.generate("datetime_now").unwrap_or_else(|| {
                    Value::String(datetime::iso8601())
                })
            },
            // 日期类型字段 - 完全基于字段类型生成，不依赖字段名称
            DataType::Date { .. } => {
                // 使用 data-forge 的日期生成能力
                forge.generate("date_now").unwrap_or_else(|| {
                    Value::String(datetime::date_iso())
                })
            },
            // 邮箱类型字段 - 完全基于字段类型生成，不依赖字段名称
            DataType::Email => {
                // 使用 data-forge 的邮箱生成能力
                forge.generate("email").unwrap_or_else(|| {
                    Value::String(internet::email())
                })
            },
            // 电话类型字段 - 完全基于字段类型生成，不依赖字段名称
            DataType::Phone { .. } => {
                // 使用 data-forge 的电话号码生成能力
                forge.generate("phone_cn").unwrap_or_else(|| {
                    Value::String(number::phone_number_cn())
                })
            },
            // UUID类型字段 - 完全基于字段类型生成，不依赖字段名称
            DataType::Uuid => {
                // 使用 data-forge 的UUID生成能力
                forge.generate("uuid_v4").unwrap_or_else(|| {
                    Value::String(crate::generators::uuid_v4())
                })
            },
            // URL类型字段 - 完全基于字段类型生成，不依赖字段名称
            DataType::Url => {
                // 使用 data-forge 的URL生成能力
                forge.generate("url").unwrap_or_else(|| {
                    Value::String(crate::generators::internet::url())
                })
            },
            // 其他类型字段
            _ => {
                // 默认生成字符串值
                Value::String(random_letters(10))
            }
        };
        data.insert(field.name.clone(), value);
    }
    
    serde_json::Value::Object(data)
}

#[cfg(test)]
mod tests {
    use super::*;
    // 在测试模块中导入 forge 宏
    use crate::forge;
    use crate::{name, datetime, internet, number};

    /// 生成示例员工数据
    fn generate_sample_employee_data(id: usize) -> Value {
        use rand::seq::SliceRandom;
        let mut rng = rand::thread_rng();
        
        let gender_options = ["M", "F"];
        let department_options = ["Engineering", "HR", "Finance", "Marketing", "Sales"];
        let position_options = ["Developer", "Manager", "Analyst", "Designer", "Tester"];
        
        forge!({
            "emp_no" => 100000 + id,
            "first_name" => name::en_first_name(),
            "last_name" => name::en_last_name(),
            "gender" => gender_options.choose(&mut rng).unwrap(),
            "birth_date" => datetime::random_date_between("1950-01-01", "2000-12-31"),
            "hire_date" => datetime::random_date_between("2000-01-01", "2023-12-31"),
            "email" => internet::email(),
            "phone" => number::phone_number_cn(),
            "salary" => number::random_int(30000, 200000),
            "department" => department_options.choose(&mut rng).unwrap(),
            "position" => position_options.choose(&mut rng).unwrap()
        })
    }
    #[test]
    fn test_random_string() {
        let s = random_letters(10);
        assert_eq!(s.len(), 10);
        assert!(s.chars().all(|c| c.is_alphanumeric()));
    }

    #[test]
    fn test_generate_sample_employee_data() {
        let employee = generate_sample_employee_data(1);
        assert!(employee.is_object());
        assert!(employee.get("emp_no").is_some());
        assert!(employee.get("first_name").is_some());
        assert!(employee.get("last_name").is_some());
        assert!(employee.get("gender").is_some());
        assert!(employee.get("birth_date").is_some());
        assert!(employee.get("hire_date").is_some());
        assert!(employee.get("email").is_some());
        assert!(employee.get("phone").is_some());
        assert!(employee.get("salary").is_some());
        assert!(employee.get("department").is_some());
        assert!(employee.get("position").is_some());
    }

    #[test]
    fn test_generate_sample_employee_data_by_schema() {
        // 创建一个简单的员工表结构
        let schema = crate::db::schema::TableSchema {
            name: "employees".to_string(),
            fields: vec![
                crate::db::schema::FieldSchema {
                    name: "emp_no".to_string(),
                    data_type: crate::db::schema::DataType::Integer { min: None, max: None },
                    constraints: crate::db::schema::FieldConstraints {
                        nullable: false,
                        unique: true,
                        default: None,
                        pattern: None,
                        min: None,
                        max: None,
                    },
                    description: None,
                    generator_config: None,
                    generator_type: None,
                },
                crate::db::schema::FieldSchema {
                    name: "first_name".to_string(),
                    data_type: crate::db::schema::DataType::String { max_length: Some(50) },
                    constraints: crate::db::schema::FieldConstraints {
                        nullable: false,
                        unique: false,
                        default: None,
                        pattern: None,
                        min: None,
                        max: None,
                    },
                    description: None,
                    generator_config: None,
                    generator_type: None,
                },
                crate::db::schema::FieldSchema {
                    name: "last_name".to_string(),
                    data_type: crate::db::schema::DataType::String { max_length: Some(50) },
                    constraints: crate::db::schema::FieldConstraints {
                        nullable: false,
                        unique: false,
                        default: None,
                        pattern: None,
                        min: None,
                        max: None,
                    },
                    description: None,
                    generator_config: None,
                    generator_type: None,
                },
            ],
            primary_key: Some(vec!["emp_no".to_string()]),
            indexes: vec![],
            description: None,
        };
        
        let employee = generate_sample_data_by_schema(&schema, 1);
        assert!(employee.is_object());
        assert!(employee.get("emp_no").is_some());
        assert!(employee.get("first_name").is_some());
        assert!(employee.get("last_name").is_some());
    }
}